C++: Model secure versions of scanf as flow sources#21856
Open
MathiasVP wants to merge 5 commits into
Open
Conversation
c81bd73 to
4d76e8d
Compare
4d76e8d to
3ea3420
Compare
c977469 to
19781e5
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds modelling of the secure scanf_s/fscanf_s/sscanf_s/... variants as local/remote flow sources. Because every string-buffer vararg in these functions is followed by a buffer-size argument, the existing "all varargs are sources" approach would incorrectly mark size integers as sources. To address this, the PR extends RemoteFlowSourceFunction::hasRemoteFlowSource and LocalFlowSourceFunction::hasLocalFlowSource with an additional Call column so a model can express that the set of source arguments depends on the specific call, and updates ScanfFunctionCall.getOutputArgument to skip size arguments for S variants.
Changes:
- Recognise the
scanf_s/fscanf_s/sscanf_s/swscanf_s/_*_s_lfamily inScanf.qlland add anisSVariantpredicate plus a size-argument detector sogetOutputArgumentskips buffer-size varargs. - Add new 3-argument
hasLocalFlowSource(Call, FunctionOutput, string)/hasRemoteFlowSource(Call, FunctionOutput, string)predicates with default bodies delegating to/from the existing 2-argument versions, and migrateScanfModel/FscanfModelplus consumers (CleartextTransmission.ql,ExternalAPIsSpecific.qll,FlowSources.qll) to the new API. - Extend scanf library tests and the source/sink dataflow tests, and add a change-note documenting the new models and API.
Show a summary per file
| File | Description |
|---|---|
| cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll | Adds S-variant detection, scanf_s/fscanf_s/sscanf_s/swscanf_s/_*_s_l recognition, and updates getOutputArgument to skip size arguments for S variants |
| cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll | Switches ScanfModel/FscanfModel to the new call-aware hasLocalFlowSource/hasRemoteFlowSource and factors logic into a shared hasFlowSource helper |
| cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll | Introduces 3-arg hasLocalFlowSource/hasRemoteFlowSource predicates with a Call column and default bodies bridging the old API |
| cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll | Uses the new call-aware predicates in RemoteModelSource and LocalModelSource |
| cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql | Uses the new call-aware hasRemoteFlowSource overload |
| cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll | Simplifies the remote-source predicate using the new call-aware API |
| cpp/ql/test/library-tests/scanf/test.c | Adds a scanf_s call and a second integer variable to exercise S-variant handling |
| cpp/ql/test/library-tests/scanf/scanfFunctionCallOutput.ql / .expected | New test query and expected output verifying getOutputArgument results |
| cpp/ql/test/library-tests/scanf/scanfFunctionCall.expected / scanfFormatLiteral.expected | Updated baselines reflecting scanf_s modelling |
| cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp | Adds inline expectations for scanf_s/fscanf_s as local/remote sources |
| cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md | Change-note describing the new models and the additional Call column on the flow-source predicates |
Copilot's findings
- Files reviewed: 13/13 changed files
- Comments generated: 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Does what it says on the tin.
There are a couple of small details that need to be fixed in order to model these as flow sources: since every string-like output buffer is succeeded by a buffer size argument we cannot blindly mark all variadic argument as an output buffer.
To fix this I've added a new version of
hasLocalFlowSourceandhasRemoteFlowSourcewith aCallcolumn. Using these new predicates thescanf_svariants can specify which output arguments of that call are sources of flow instead of marking all of them.Commit-by-commit review recommended.